﻿from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtUiTools import *
import os

class PluginManager(QObject):
    ui = None
    parentObj = None
    enabledActions = []

    def __init__(self, parent):
        super(PluginManager, self).__init__()
        self.parentObj = parent

        qApp.pluginManager = self

        uifile = QFile("PluginManager.ui")
        if not uifile.open(QIODevice.ReadOnly):
            sys.exit(1)
        uiloader = QUiLoader()
        self.ui = uiloader.load(uifile, parent.ui)
        if self.ui == None:
            sys.exit(2)

        self.btnAddPlugin = self.ui.findChild(QPushButton, "btnAddPlugin")
        self.btnRemovePlugin = self.ui.findChild(QPushButton, "btnRemovePlugin")
        self.btnEnDisable = self.ui.findChild(QPushButton, "btnEnDisable")
        self.btnMoveUp = self.ui.findChild(QPushButton, "btnMoveUp")
        self.btnMoveDown = self.ui.findChild(QPushButton, "btnMoveDown")

        self.btnOpenPluginsFolder = self.ui.findChild(QPushButton, "btnOpenPluginsFolder")
        self.btnMasterScript = self.ui.findChild(QPushButton, "btnMasterScript")

        self.ui.setWindowFlags(Qt.Tool)
        self.ui.installEventFilter(self)
        uifile.close()

        self.tableWidget = self.ui.findChild(QTableWidget, "tableWidget")
        self.plainTextEdit = self.ui.findChild(QPlainTextEdit, "plainTextEdit")

        self.btnAddPlugin.clicked.connect(self.onAddPlugin)
        self.btnRemovePlugin.clicked.connect(self.onRemovePlugin)
        self.btnEnDisable.clicked.connect(self.onEnDisable)
        self.btnMoveUp.clicked.connect(self.onMoveUp)
        self.btnMoveDown.clicked.connect(self.onMoveDown)

        self.btnOpenPluginsFolder.clicked.connect(self.onOpenPluginsFolder)
        self.btnMasterScript.clicked.connect(self.onMasterScript)

        self.tableWidget.itemDoubleClicked.connect(self.onItemDoubleClick);

        self.tableWidget.horizontalHeader().resizeSection(0, 150)
        self.tableWidget.horizontalHeader().resizeSection(1, 75)
        self.tableWidget.horizontalHeader().resizeSection(2, 130)
        self.tableWidget.horizontalHeader().resizeSection(3, 130)
        self.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
        self.tableWidget.horizontalHeader().setSectionResizeMode(1, QHeaderView.Fixed)
        self.tableWidget.horizontalHeader().setSectionResizeMode(2, QHeaderView.Fixed)
        self.tableWidget.horizontalHeader().setSectionResizeMode(3, QHeaderView.Fixed)

        self.updatePluginTable()        

    def updatePluginTable(self):
        rowCount = self.tableWidget.rowCount()
        for i in range(0, rowCount):
            self.tableWidget.removeRow(0)

        for i in range(0, len(self.enabledActions)):
            self.parentObj.menuPlugins.removeAction(self.enabledActions[i])
        self.enabledActions = []

        dir = QDir(self.pluginsFolder())
        files = dir.entryInfoList(QDir.Files)
        masterFilePath = ""
        for file in files:
            if file.fileName().lower() == "master.py":
                masterFilePath = file.absoluteFilePath()
                continue
            if file.size() > 1024 * 10:
                continue
            self.pushFileInTable(file)

        self.executeScript(masterFilePath)

    def pushFileInTable(self, fileInfo):
        count = self.tableWidget.rowCount()
        self.tableWidget.insertRow(count)
        file = QFile(fileInfo.absoluteFilePath())
        if file.open(QIODevice.ReadOnly):
            content = file.readAll()
            file.close()
            strContent = str(content, encoding="utf-8")
            regexp = QRegExp("\\#\\s*\\@name\\s+(.*)\\\n")
            regexp.setMinimal(True)
            index = regexp.indexIn(strContent)

            scriptName = fileInfo.baseName()
            if index > 0:
                scriptName = regexp.cap(1).strip()

            regexp = QRegExp("\\#\\s*\\@enabled\\s+(.*)\\\n")
            regexp.setMinimal(True)
            index = regexp.indexIn(strContent)
            isEnabledStr = "enabled"
            if index > 0:
                enabled = regexp.cap(1).strip().lower()
                if enabled == "true":
                    isEnabledStr = "enabled"
                    action = self.parentObj.menuPlugins.addAction(scriptName)
                    action.triggered.connect(self.onPluginActionTriggered)
                    self.enabledActions.append(action)
                    action.setData(fileInfo.absoluteFilePath())
                else:
                    isEnabledStr = "disabled"

        nameitem = QTableWidgetItem(scriptName)
        nameitem.setData(0xFFFF, fileInfo.absoluteFilePath())
        self.tableWidget.setItem(count, 0, nameitem)
        self.tableWidget.setItem(count, 1, QTableWidgetItem(isEnabledStr))
        self.tableWidget.setItem(count, 2, QTableWidgetItem(fileInfo.birthTime().toString("yyyy-MM-dd hh:mm:ss")))
        self.tableWidget.setItem(count, 3, QTableWidgetItem(fileInfo.lastRead().toString("yyyy-MM-dd hh:mm:ss")))

    def executeScript(self, filePath):
        fileName = QFileInfo(filePath).fileName()
        file = QFile(filePath)
        if not file.open(QIODevice.ReadOnly):
            return;
        content = file.readAll()
        p = compile(content, fileName, 'exec')
        exec(p)

    def onPluginActionTriggered(self):
        action = self.sender()
        filePath = action.data()
        self.executeScript(filePath)

    def show(self):
        self.updatePluginTable()
        self.ui.show()
        qApp.setActiveWindow(self.ui)
        self.ui.setFocus()

    def eventFilter(self, obj, event):
        if obj == self.ui and event.type() == QEvent.KeyPress:
            if event.key() == Qt.Key_Escape:
                self.ui.close()
        return False

    def pluginsFolder(self):
        dir = QDir(qApp.applicationDirPath())
        if not dir.exists("plugins"):
            if not dir.mkdir("plugins"):
                print("mkdir plugins failed")
        dir.cd("plugins")
        return dir.absolutePath()

    def onItemDoubleClick(self, item):
        nameItem = self.tableWidget.item(item.row(), 0)
        fileName = nameItem.data(0xFFFF)
        self.parentObj.openFileByName(fileName)

    def onAddPlugin(self):
        tempScript = self.pluginsFolder() + "/" + QUuid.createUuid().toString()[1:8] + ".py"
        self.createScriptFile(tempScript)
        self.parentObj.openFileByName(tempScript)
        self.pushFileInTable(QFileInfo(tempScript))

    def onRemovePlugin(self):
        pass

    def onEnDisable(self):        
        curRow = self.tableWidget.currentRow()
        nameItem = self.tableWidget.item(curRow, 0)
        fileName = nameItem.data(0xFFFF)
        isEnabledStr = False
        itemEnabledText = "enabled"
        if self.tableWidget.item(curRow, 1).text().lower() == "enabled":
            isEnabledStr = True
            switchEnabledStr = "false"
            itemEnabledText = "disabled"
        else:
            isEnabledStr = False
            switchEnabledStr = "true"
            itemEnabledText = "enabled"

        file = QFile(fileName)
        if file.open(QIODevice.ReadOnly):
            content = file.readAll()
            file.close()
            strContent = str(content, encoding="utf-8")
            regexp = QRegExp("\\#\\s*\\@enabled\\s+(.*)\\\n")
            regexp.setMinimal(True)
            index = regexp.indexIn(strContent)
            print(switchEnabledStr)
            strContentNew = strContent[:index] + "# @enabled    " + switchEnabledStr + "\n" + strContent[index + regexp.matchedLength():]
            file.close()
            if file.open(QIODevice.WriteOnly):
                file.write(bytes(strContentNew, encoding="utf-8"))
                file.close()
                self.tableWidget.item(curRow, 1).setText(itemEnabledText)

    def onMoveUp(self):
        pass
    def onMoveDown(self):
        pass
    def onOpenPluginsFolder(self):
        pluginPath = self.pluginsFolder()
        url = QUrl.fromLocalFile(pluginPath)
        QDesktopServices.openUrl(url)

    def onMasterScript(self):
        dir = QDir(self.pluginsFolder())
        masterFile = dir.absolutePath() + "/master.py"
        if not dir.exists("master.py"):
            self.createScriptFile(masterFile, False)
        self.parentObj.openFileByName(masterFile)

    def createScriptFile(self, fileName, isPlugin = True):
        file = QFile(fileName)
        if file.open(QIODevice.WriteOnly):
            pluginContent1 = b'''# python script
# @name        '''

            pluginContent2 = b'''
# @enabled      true
# @version      0.1
# @description
# @author       You
# @match        *.*
# python script

'''
            content = b'''#code begin
#qApp.mainApp, qApp.pluginManager, qApp.prefrences, qApp.searchWindow


'''
            if isPlugin:
                file.write(pluginContent1)
                file.write(bytes(QFileInfo(fileName).baseName(), encoding="utf-8"))
                file.write(pluginContent2)
            file.write(content)
            file.close()
